﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;

using Jarvis.Sensors;
using Jarvis.Utility;

namespace Jarvis.Analytics
{
    class AnalyticsManager
    {
        protected Timer snapshotTimer;
        private List<Dictionary<string, object>> pendingEvents;

        private static AnalyticsManager instance;

        public static void LogEvent(string kind, string value)
        {
            if (instance != null)
                instance.AddEvent(kind, value);
        }

        public static XmlDocument XmlForState(Dictionary<string, object> state, List<Dictionary<string, object>> eventList)
        {
            XmlDocument doc = new XmlDocument();

            doc.LoadXml("<snapshot />");

            XmlElement snapshot = doc.DocumentElement;
            snapshot.SetAttribute("date", DateTime.Now.ToString());

            foreach (Dictionary<string, object> eventDict in eventList)
            {
                XmlElement node = doc.CreateElement("event");

                foreach (string key in eventDict.Keys)
                    node.SetAttribute(key, eventDict[key].ToString());

                snapshot.AppendChild(node);
            }

            foreach (String key in state.Keys)
            {
                XmlElement node = doc.CreateElement("sensor");
                node.SetAttribute("name", key);

                object reading = state[key];

                if (reading is List<object>)
                {
                    foreach (object item_object in (reading as List<object>))
                    {
                        if (item_object != null)
                        {
                            XmlElement item = doc.CreateElement("item");

                            item.AppendChild(doc.CreateTextNode(item_object.ToString()));

                            node.AppendChild(item);
                        }
                    }                   
                }
                else
                    node.AppendChild(doc.CreateTextNode(reading.ToString()));

                snapshot.AppendChild(node);
            }

            return doc;
        }

        public static String StringForXml(XmlDocument doc)
        {
            MemoryStream stream = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(stream, Encoding.Unicode);

            writer.Formatting = Formatting.Indented;

            doc.WriteContentTo(writer);
            writer.Flush();
            stream.Flush();

            stream.Position = 0;

            StreamReader reader = new StreamReader(stream);

            return reader.ReadToEnd();
        }

        public void AddEvent(string kind, string value)
        {
            Console.WriteLine(kind + ": " + value);

            Dictionary<string, object> eventDict = new Dictionary<string, object>();
            eventDict["kind"] = kind;
            eventDict["value"] = value;
            eventDict["date"] = DateTime.Now;

            pendingEvents.Add(eventDict);
        }


        public AnalyticsManager()
        {
            this.snapshotTimer = new Timer(new TimerCallback(this.SaveSnapshot), null, 0, 10000); // 300000);
            instance = this;

            pendingEvents = new List<Dictionary<string, object>>();
        }

        public virtual void SaveSnapshot(Object stateInfo)
        {
            if (Preferences.preferences.Get("Log Analytics") != null && (Boolean)Preferences.preferences.Get("Log Analytics"))
            {
                SensorNotifier notifier = SensorNotifier.Instance;

                Dictionary<String, object> state = notifier.getState();

                if (state != null)
                {
                    String xmlString = StringForXml(XmlForState(state, pendingEvents));
                    DateTime now = DateTime.Now;

                    String desktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Jarvis\\Analytics\\"
                                                + now.Year + "-" + now.Month + "-" + now.Day + "\\";

                    if (!Directory.Exists(desktopFolder))
                        Directory.CreateDirectory(desktopFolder);

                    String appData = now.Hour + "." + now.Minute + "." + now.Second + ".xml";

                    TextWriter writer = new StreamWriter(desktopFolder + appData);
                    writer.Write(xmlString);
                    writer.Close();
                }
            }

            pendingEvents.Clear();
        }
    }
}
